2026-09-24 · class-notes, powershell, providers, psdrive, registry, filesystem
Full class notes on PowerShell providers and PSDrives: what providers are, filesystem organisation, other data stores as drives, navigation, and wildcards vs literal paths.
Class notes · Learn PowerShell in a Month of Lunches (3rd ed.), Don Jones & Jeffery Hicks · Chapter 5
Note on this file's sourcing: no transcript or scanned text was available for this chapter, only its section headings. These notes are written from general PowerShell knowledge, independently verified against Microsoft's own PowerShell documentation rather than reconstructed from the book's wording — they are not a paraphrase of Jones and Hicks' text. Treat this chapter's material with that in mind, and let me know if anything here doesn't match what you find in your physical copy.
Quick reference: the short version of this chapter is the PowerShell chapter 5 sheet. It builds on chapter 4, Running commands, and gives you the vocabulary — providers and drives — used throughout the rest of the book whenever you touch the registry, certificates, or anything that isn't the filesystem.
By the end of these notes you should be able to:
-LiteralPath.Different kinds of data live in very different places: files on disk, keys and values in the Windows registry, certificates in a certificate store, variables in memory, environment settings. Each of these has its own native way of being addressed and manipulated. Without a common abstraction, you would need an entirely different set of commands for each one.
A PowerShell provider is a piece of software that makes a data store look and behave like a filesystem drive, so the same small set of cmdlets — Get-ChildItem, Get-Item, Set-Location, New-Item, Remove-Item, and so on — works against it, regardless of what the underlying data actually is.
+------------------------------------------------------------------------------+
| |
| Without a provider abstraction With a provider abstraction |
| |
| Files: dir, copy, del Get-ChildItem, Copy-Item, Remove-Item|
| Registry: reg query, reg add Get-ChildItem, New-Item, Set-Item... |
| Env vars: set, echo %VAR% Get-ChildItem, Get-Item, Set-Item... |
| Certs: certutil Get-ChildItem, Get-Item... |
| |
| four different tool sets one consistent set of cmdlets |
| working against several drives |
| |
+------------------------------------------------------------------------------+
A provider is the underlying mechanism — the "driver" that knows how to talk to a particular kind of data store. A PSDrive is a specific, named instance of that provider, mounted at a particular root — much as C: and D: are two different drives that both happen to use the same FileSystem provider.
One provider can back more than one drive. The FileSystem provider backs every disk drive letter on your system; the Registry provider backs both HKLM: and HKCU:.
Get-PSProvider
Get-PSDrive
Get-PSProvider lists the providers loaded in your session; Get-PSDrive lists the actual mounted drives, including ones backed by providers other than FileSystem.
| Provider | Default drive(s) | Windows-only? |
|---|---|---|
| Alias | Alias: |
No |
| Environment | Env: |
No |
| FileSystem | C:, D:, etc. |
No |
| Function | Function: |
No |
| Variable | Variable: |
No |
| Registry | HKLM:, HKCU: |
Yes |
| Certificate | Cert: |
Yes |
| WSMan | WSMan: |
Yes |
I checked this list, and the Windows-only status of Registry, Certificate and WSMan, against Microsoft's own PowerShell documentation. On non-Windows platforms (Linux, macOS), only Alias, Environment, FileSystem, Function and Variable are present.
Note (beyond this lesson): the third edition of this book targets PowerShell running primarily on Windows, so all eight providers above are fair game throughout the rest of the material. If you're following along on PowerShell 7 on Linux or macOS, expect
HKLM:,HKCU:,Cert:andWSMan:to simply not exist.
The filesystem — and every hierarchical provider modelled on it — is organised as a tree of containers (folders/directories, and the registry's keys) holding items (files, and the registry's values). A container can hold other containers, items, or both.
A path such as C:\Users\Alice\Documents\report.docx describes a walk down that tree: drive, then a sequence of nested containers, ending at an item. The same logic applies to a registry path like HKLM:\SOFTWARE\Microsoft\Windows, even though the underlying data is nothing like a file.
| Cmdlet | Purpose |
|---|---|
Get-Location |
Show the current location (like pwd) |
Set-Location |
Change the current location (like cd) |
Get-ChildItem |
List the containers/items directly beneath the current location |
Get-Item |
Get the item (or container) at a specific path |
Push-Location / Pop-Location |
Save the current location on a stack, then return to it later |
Set-Location, Get-ChildItem and Get-Item all have the common aliases cd/sl, dir/gci/ls, and gi respectively, which is why PowerShell feels immediately familiar to anyone coming from either cmd.exe or a Unix shell.
Because a provider makes its data store look like a filesystem, the very same cmdlets used for files and folders work, largely unchanged, against the registry, environment variables, or certificates — you are just pointed at a different drive.
Task: list the subkeys directly under HKLM:\SOFTWARE\Microsoft, the same way you would list a folder's contents.
Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft
This is structurally identical to Get-ChildItem -Path C:\Program Files — one lists registry subkeys, the other lists folders, but it is the same cmdlet, the same syntax, and the same mental model.
Task: view all environment variables, then read and change one specific value, using filesystem-style cmdlets rather than $env: syntax.
Get-ChildItem -Path Env:
Get-Item -Path Env:TEMP
Set-Item -Path Env:MY_VAR -Value "hello"
Get-ChildItem -Path Env: lists every environment variable as though it were a file in a folder called Env:. Get-Item reads a single one; Set-Item writes to one — the same verbs used everywhere else in PowerShell, applied here to environment variables instead of files.
Registry keys map onto containers (like folders); registry values map onto item properties (not separate child items the way files are). To read or change a value inside a key, you use the *-ItemProperty cmdlets rather than *-Item:
Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion
Set-ItemProperty -Path HKCU:\Software\MyApp -Name "Setting1" -Value "On"
Exam tip (for study, not a certification exam here — but worth memorising anyway): in the registry provider, a key is a container, reached with
*-Item/*-ChildItem; a value inside that key is a property, reached with*-ItemProperty. Confusing the two is the single most common beginner mistake when scripting registry changes.
Because every hierarchical provider looks like a filesystem, the navigation cmdlets from section 2.3 work identically no matter which drive you are on. Moving from C: to HKLM: is conceptually the same operation as moving from C:\ to D:\.
Set-Location -Path HKLM:\SOFTWARE
Get-ChildItem
Set-Location -Path C:\
PowerShell supports the same relative-path conventions as a traditional shell: . for the current location, .. for the parent, and a bare name to move into a child container — all working the same way regardless of provider.
Test-Path -Path C:\Windows\System32
Test-Path -Path HKLM:\SOFTWARE\DoesNotExist
Test-Path works against any provider's paths and returns $true or $false, letting a script check before acting rather than relying on an error.
By default, -Path accepts wildcards. * matches any sequence of characters, and ? matches a single character, the same conventions used in the shell generally.
Get-ChildItem -Path C:\Windows\*.log
Sometimes a path genuinely contains a character that would otherwise be interpreted as a wildcard — most commonly [ or ], which are legitimate characters in some real filenames and registry key names, but which PowerShell would otherwise try to interpret as a wildcard character class.
Get-ChildItem -LiteralPath 'C:\Reports\[Draft] Q3 Summary.docx'
-LiteralPath tells the cmdlet to treat the string exactly as written, with no wildcard expansion at all.
Caution: this is a genuinely common gotcha when scripting against real-world file or registry names that include brackets.
-Pathand-LiteralPathare mutually exclusive on a given cmdlet call — use one or the other, never both.
Scenario: a file is genuinely named Log[2026].txt, and Get-ChildItem -Path 'Log[2026].txt' reports nothing found, even though the file is clearly present in the folder.
[ and ] are wildcard characters (a character class) to PowerShell's -Path parameter, so [2026] is being read as "any single character that is 2, 0, 6, or 9," not as literal text.-LiteralPath: Get-ChildItem -LiteralPath 'Log[2026].txt'.On Windows, the Certificate provider exposes the certificate stores through Cert::
Get-ChildItem -Path Cert:\CurrentUser\My
This lists certificates in the current user's personal certificate store, using exactly the same Get-ChildItem you would use to list files.
The WSMan provider, also Windows-only, exposes PowerShell Remoting's own configuration as a drive, typically requiring administrative rights to browse or change:
Get-ChildItem -Path WSMan:\localhost
New-PSDrive lets you mount a new, custom drive against an existing provider — commonly used to give a long or awkward path a short, memorable name for the rest of a session:
New-PSDrive -Name Reports -PSProvider FileSystem -Root 'D:\Shared\Reports\2026'
Set-Location Reports:
A drive created this way exists only for the current PowerShell session unless you take extra steps to persist it; it disappears the moment the session ends.
Scenario: you are writing a script that repeatedly reads and writes files under a long, deeply nested path, and want to shorten every reference to it for the length of the script.
New-PSDrive -Name Rpt -PSProvider FileSystem -Root '\\fileserver\shared\quarterly\reports\2026'.Get-ChildItem -Path Rpt:\ instead of repeating the full UNC path.Remove-PSDrive -Name Rpt, though this isn't strictly necessary since it won't persist to the next session anyway.New-PSDrive call, or the drive needs to be created as part of a profile script if it should be available every time.Providers are a convenience feature, but treating sensitive data stores as "just another drive" has real security implications.
Remove-Item -Path HKLM:\... -Recurse is exactly as dangerous as Remove-Item -Path C:\... -Recurse, and just as easy to run by mistake. Treat registry and certificate operations in a script with the same caution (confirmation prompts, -WhatIf, testing on a non-production system first) that you would apply to filesystem deletions.-WhatIf and -Confirm work across providers, not just the filesystem — a script that changes registry values or certificates should use them during testing exactly as it would for file operations, since the underlying cmdlets are the same ones.Remove-Item against HKLM: can remove far more than intended, with none of the "oh, I can just restore from the recycle bin" safety net that files sometimes offer. Prefer -LiteralPath or fully-qualified exact paths for anything destructive against non-filesystem providers.Cert: and WSMan: browsing often needs elevated privileges, which is itself a signal: a script that needs to touch these drives is operating with more authority than an ordinary file-manipulation script, and should be reviewed accordingly before being run or scheduled unattended.New-PSDrive are session-scoped by default, which is a mild safety feature — a drive mapped during an interactive troubleshooting session doesn't silently persist as a standing, possibly forgotten access path once that session ends.Get-ChildItem, Get-Item, Set-Location, New-Item, Remove-Item, Test-Path — works against any provider's drives.*-Item/*-ChildItem); registry values are item properties (use *-ItemProperty).*, ?); use -LiteralPath when a path genuinely contains characters like [ or ] that would otherwise be misread as wildcards.Get-PSProvider lists providers; Get-PSDrive lists drives; New-PSDrive creates a custom, typically session-scoped drive.| Term | Meaning |
|---|---|
| Provider | Software that exposes a data store using filesystem-style cmdlets |
| PSDrive | A specific, named, mounted instance of a provider |
| Container | A location that can hold other containers or items (a folder, a registry key) |
| Item | A leaf object within a container (a file, a registry value's parent key) |
| Item property | A named value attached to an item, such as a registry value |
| FileSystem provider | The built-in provider backing disk drives |
| Registry provider | The Windows-only provider exposing HKLM: and HKCU: |
| Certificate provider | The Windows-only provider exposing certificate stores as Cert: |
| WSMan provider | The Windows-only provider exposing remoting configuration |
| Wildcard | A pattern character (*, ?, [ ]) expanded against matching paths |
| Literal path | A path taken exactly as written, with no wildcard expansion |
Get-PSProvider |
Lists the providers available in the current session |
Get-PSDrive |
Lists the drives mounted in the current session |
New-PSDrive |
Creates a new, typically session-scoped drive |
*-ItemProperty rather than *-Item to read a registry value?Test-Path do, and against how many different providers does it work?-Path parameter?-Path fail to find a file whose name contains square brackets?-LiteralPath do differently from -Path?-Path and -LiteralPath both be supplied to the same cmdlet call?New-PSDrive do, and how long does a drive it creates typically persist?HKCU:\Software\MyApp. Which family of cmdlets do you use, and why not Remove-Item?Data[Final].csv, and Get-ChildItem -Path 'Data[Final].csv' returns nothing. What's happening, and how do you fix it?Rpt:, pointing at a long UNC path for the rest of today's session only. Which cmdlet do you use, and what happens to the drive tomorrow?C: and D: both being instances of the FileSystem provider.Get-PSProvider lists providers; Get-PSDrive lists drives.Get-ChildItem -Path HKLM:\... (or whichever registry path), exactly as you would list a folder.*-Item/*-ChildItem cmdlets address keys (containers), while *-ItemProperty cmdlets address the values inside them.$true or $false. It works against any provider's paths.* (any sequence of characters) and ? (a single character).-Path, so a filename containing them can be misread as a pattern rather than literal text.-Path and -LiteralPath are mutually exclusive on a single cmdlet call.Get-ChildItem -Path Env:*-ItemProperty cmdlets (specifically Remove-ItemProperty) — Remove-Item would target the key itself (the container), not a single value within it.[Final] as a wildcard character class, not literal text. Use Get-ChildItem -LiteralPath 'Data[Final].csv' instead.New-PSDrive -Name Rpt -PSProvider FileSystem -Root '\\path\to\share'. Being session-scoped by default, the drive is gone once today's session ends — it will not be there tomorrow unless recreated or made persistent.